/**
 * 
 */
package ca.biosample.robot.serial;

import java.io.UnsupportedEncodingException;
import java.util.Vector;

import gnu.io.SerialPort;

/**
 * @author Mike Sokolsky
 *
 * This class provides simple access to an IAI X-SEL controller via the
 * teaching pendant serial connection.
 */
public class RobotInterface {

	static final String EXECUTE_PROGRAM = "253";
	static final String COMM_PORT = "COM6";
	
	SerialInterface robot;

	// This will never change for the X-SEL we are using
	static final String COMMAND_HEADER = "!99";
	static final String CRLF = "/r/n";
	// The command station ID in ASCII-encoded hex.  This should be "99"
	static final byte COMMAND_STATION1 = 0x39;
	static final byte COMMAND_STATION2 = 0x39;
	// Some handy ASCII codes, perhaps these are defined already somewhere?
	static final byte ASCII_BANG = 0x21;
	static final byte ASCII_CR = 0x0D;
	static final byte ASCII_NL = 0x0A;
	static final byte ASCII_AT = 0x40;
	
	/**
	 * Create a new RobotInterface
	 * 
	 * @param portName String for the port to connect on
	 */
	public RobotInterface(String portName) {
		robot = new SerialInterface(portName, 
				38400, 
				SerialPort.DATABITS_8,
				SerialPort.STOPBITS_1, 
				SerialPort.PARITY_NONE);
	}
	
	/**
	 * Sends a command to the robot as specified by arguments
	 * 
	 * @TODO:  Should return something useful :) 
	 * 
	 * @param num Command in Hex
	 * @param content Value of command
	 */
	public void sendCommand(String num, String content) {

		// Command header, should never change;
		String commandString = COMMAND_HEADER;
		commandString += num;
		commandString += content;
		// Cheat on the checksum by sending @@, 
		// @TODO: fix this.
		commandString += "@@";
		commandString += CRLF;
		
		robot.writeString(commandString);
		try {
			Thread.sleep(100);
		} catch (Exception e) {};
		System.out.println(robot.readString());
		
		// The above should replace all of the below I think.
		
		/*
		// Build our command in this vector
		Vector<Byte> command = new Vector<Byte>();
		int checksum = 0;
		// @TODO:  how long can a response be?
		byte[] response = new byte[100];

		// Add header, this should not change in the foreseeable future,
		// so we'll add things by hand.
		command.add(ASCII_BANG);
		checksum += ASCII_BANG;
		command.add(COMMAND_STATION1);
		checksum += COMMAND_STATION1;
		command.add(COMMAND_STATION2);
		checksum += COMMAND_STATION2;
		
		// Convert the argument strings to ASCII
		byte[] numAsBytes;
		byte[] contentAsBytes;
		try {
			numAsBytes = num.getBytes("US-ASCII");
			contentAsBytes = content.getBytes("US-ASCII");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return;
		}
		
		// Add the argument strings to the command.
		// Note: we're not doing any input verification here.
		// Perhaps that should be added.
		for(int i = 0; i < numAsBytes.length; i++) {
			command.add(numAsBytes[i]);
			checksum += numAsBytes[i];
		}
		for(int i = 0; i < contentAsBytes.length; i++) {
			command.add(contentAsBytes[i]);
			checksum += contentAsBytes[i];
		}
		
		// The tail of the packet.  The checksum system used by the system
		// is extremely weak, and a small pain to implement in Java, so we are
		// bypassing it right now by sending '@@'.
		command.add(ASCII_AT);
		command.add(ASCII_AT);
		command.add(ASCII_CR);
		command.add(ASCII_NL);
		
		// Now we build the final packet.  Java makes this difficult, the
		// following works, however there is hopefully a more efficient 
		// way of getting a Vector<Byte> into a byte[].
		Byte[] byteCommand = new Byte[command.size()];
		command.toArray(byteCommand);
		byte[] bytes = new byte[byteCommand.length];
		for(int i = 0; i < bytes.length; i++ )
			bytes[i] = byteCommand[i].byteValue();

		// Send the data, then wait for a response.  This should be correlated
		// with the maximum amount of data in a response packet and the baud
		// rate of the serial link.
		robot.write(bytes);
		try {
			Thread.sleep(100);
		} catch (Exception e) {};
		int len = robot.read(response);
		System.out.print(new String(response, 0, len));*/
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
	
		RobotInterface reader = new RobotInterface(COMM_PORT);
		reader.sendCommand("253", "1F");
		while(true) {
			//reader.sendCommand("200","0123456789");

			try{
				Thread.sleep(5000);
			} catch ( Exception e ) {};
		}
	}
}